package com.kongyz.server;


import com.kongyz.protocol.RpcRequest;
import com.kongyz.protocol.RpcResponse;
import io.netty.channel.*;
import net.sf.cglib.reflect.FastClass;
import net.sf.cglib.reflect.FastMember;
import net.sf.cglib.reflect.FastMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.Map;


public class RpcHandler extends ChannelHandlerAdapter {

    private static final Logger logger= LoggerFactory.getLogger(RpcHandler.class);

    private final Map<String,Object> handlerMap;

    public RpcHandler(Map<String, Object> handlerMap) {
        this.handlerMap = handlerMap;
    }

    @Override
    public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
        final RpcRequest request=(RpcRequest)msg;
        RpcServer.submit(new Runnable() {
            @Override
            public void run() {
                logger.debug("接收到的 Request :"+request.getRequestId());
                RpcResponse response=new RpcResponse();
                response.setRequestId(request.getRequestId());
                try {
                    Object result=handle(request);
                    response.setResult(result);
                }catch (Throwable t){
                    response.setError(t.toString());
                    logger.error("Rpc Service handle request error",t);
                }
                ctx.writeAndFlush(response).addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        logger.debug("发送对于{0}的处理结果",request.getRequestId());
                    }
                });
            }
        });
    }

    public void channelRead(final ChannelHandlerContext ctx, final RpcRequest request) throws Exception {
        System.out.println(111);
    }

    /**
     * 动态代理处理远程函数
     * @param request
     * @return
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private Object handle(RpcRequest request) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        String className=request.getClassName();
        Object serviceBean=handlerMap.get(className);

        Class<?> serviceClass=serviceBean.getClass();
        String methodName=request.getMethodName();

        Class<?>[] parameterTypes=request.getParameterTypes();
        Object[] parameters=request.getParameters();

        logger.debug("接受到的类：{}",serviceClass.getName());
        logger.debug("接受到的方法：{}",methodName);

        for (int i=0;i< parameterTypes.length;i++){
            logger.debug("方法参数类型：{}",parameterTypes[i].getName());
        }
        for(int i=0;i<parameters.length;i++){
            logger.debug("方法参数名称：{}",parameters[i].toString());
        }

        //JDK reflect  JDK自带的动态代理 映射
//        Method method=serviceClass.getMethod(methodName,parameterTypes);
//        method.setAccessible(true);
//        return method.invoke(serviceBean,parameters);

        //CGLIB reflect  CGlIB 动态代理 映射
        FastClass serviceFastClass=FastClass.create(serviceClass);
        FastMethod serviceFastMethod=serviceFastClass.getMethod(methodName,parameterTypes);
        return serviceFastMethod.invoke(serviceBean,parameters);

    }

    /**
     * @param ctx
     * @param cause
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        ctx.close();
    }

}
